// NormalMenuBbsState.cpp: implementation of the CNormalMenuBbsState class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "NormalMenuBbsState.h"
#include "resource.h"
#include "strFuncs.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CNormalMenuBbsState::CNormalMenuBbsState()
{
	
}

CNormalMenuBbsState::~CNormalMenuBbsState()
{

}

BOOL CNormalMenuBbsState::CheckState(CAnsiScreen *pScreen, CPoint ptCursorCell, IBbsState *pPrevState)
{
	CBaseBbsState::CheckState(pScreen, ptCursorCell, pPrevState);
	collectMenuRects();
	if(m_menuItems.GetSize() > 1)
	{
		return TRUE;
	}
	return FALSE;
}

BOOL CNormalMenuBbsState::OnClick(CPoint ptCursorCell)
{
	int count = m_menuItems.GetSize();
	for(int n = 0; n < count; n++)
	{
		MenuItem &item = m_menuItems[n];
		if( ptOnRect(item, &ptCursorCell) )
		{
			m_pKeyboard->OnChar(item.accessChar , 0);
			m_pKeyboard->OnChar(VK_RETURN, 0);
			return TRUE;
		}
	}
	return FALSE;
}

BOOL CNormalMenuBbsState::OnMouseMove(CPoint ptCell, UINT nFlags)
{
	HCURSOR hCursor = NULL;
	
	int itemIndex = -1;
	int count = m_menuItems.GetSize();
	MenuItem* pItem = m_menuItems.GetData();
	for(int n = 0; n < count; n++, pItem++)
	{
		if(( ptCell.x >= pItem->left) && (ptCell.x <= pItem->right) && 
			(ptCell.y >= pItem->top) && (ptCell.y <= pItem->bottom) )
		{
			hCursor = LoadCursor(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_HAND1));
			itemIndex = n;
			break;
		}
	}
	if(itemIndex != m_oldItemIndex)
	{
		if(m_oldItemIndex != -1)
		{
			setScreenEffects(m_menuItems[m_oldItemIndex], EffectNone);
		}
		if(itemIndex != -1)
		{
			setScreenEffects(m_menuItems[itemIndex], EffectHighlight);
		}
		m_oldItemIndex = itemIndex;
	}
	
	m_pScreen->SetCursor(hCursor);
	return BOOL(hCursor);
}

void CNormalMenuBbsState::collectMenuRects()
{
	clearOldRect();
	CSize sizeScr = m_pScreen->GetSize();
	char** chars = m_pScreen->GetChars();
	m_menuItems.RemoveAll();

	int n, count;
	int x, y;
	int x1, x2, y1, y2;
	UNUSED_ALWAYS(x1);	UNUSED_ALWAYS(y1);	UNUSED_ALWAYS(x2);	UNUSED_ALWAYS(y2);

	int maxWidth = 0;
	
	for(y = 0; y <= sizeScr.cy - 1; y++)
	{
		for(x = 0; x < sizeScr.cx - 2; x++)
		{
			char c = chars[y][x];
			if(!strFuncs::IsGBKSecondByte(chars[y], x) && isMenuAccessChar(c))
			{
				char c1 = chars[y][x + 1];
				if( (c1 == ')') || (c1 == ']') || (c1 == '}') || 
					((c1 == '.')))// && ((chars[y][x + 2] == 32) || strFuncs::CheckUrl(chars[y], x + 1).IsEmpty())) )
				{
					x1 = x;
					if(x1 > 0)
					{
						char c0 = chars[y][x - 1];
						if((c0 == '(') || (c0 == '[') || (c0 == '{'))
						{
							--x1;
						}
						else if(c0 != 32)
						{
							continue;
						}
					}
					MenuItem menuItem(x1, y, sizeScr.cx - 1, y);
					menuItem.accessChar = c;
					menuItem.delimChar = c1;

					int index = m_menuItems.Add(menuItem);

					if(index > 0)
					{
						MenuItem *pItems = m_menuItems.GetData();
						MenuItem *pPrevItem = pItems + index - 1;
						MenuItem *pCurItem = pItems + index;

						int prevRight = pPrevItem->right;
						if(pPrevItem->top == pCurItem->top)
						{
							compactMenuItem(pPrevItem, x - 1);
							if(pPrevItem->right == x - 1)
							{
								pPrevItem->right = pCurItem->right;
								m_menuItems.RemoveAt(index);
							}
						}
						else
						{
							compactMenuItem(pPrevItem, pPrevItem->right);
						}
					}
				}
			}
		}
	}

	removeLessPatternItems();

	count = m_menuItems.GetSize();
	if(count == 0)
	{
		return;
	}
	MenuItem *pItems = m_menuItems.GetData();
	MenuItem *pLastItem = pItems + count - 1;
	compactMenuItem(pLastItem, pLastItem->right);
	
	for(n = 0; n < count; n++)
	{
		MenuItem *pItem = pItems + n;
		int width = pItem->Width();
		if( width > maxWidth )
		{
			maxWidth = width;
		}
	}

	BOOL bOverflow = FALSE;
	for(n = 0; n < count; n++)
	{
		MenuItem *pItem = pItems + n;
		if(pItem->left + maxWidth > sizeScr.cx - 1)
		{
			bOverflow = TRUE;
			break;
		}
	}
			
	if(pLastItem->left + maxWidth > sizeScr.cx - 1)
	{
		bOverflow = TRUE;
	}
	if(!bOverflow)
	{
		for(n = 0; n < count; n++)
		{
			MenuItem *pItem = pItems + n;
			pItem->right = pItem->left + maxWidth;
		}
	}
	for(n = 0; n < count; n++)
	{
		MenuItem *pItem = pItems + n;
		ASSERT(pItem->right < 80);
	}
}
